/*******************************************************************
版权声明：       HITCRT-iHiter(哈工大竞技机器队RoboMaster iHiter战队)
文件名：         rm_rs_types.h
最近修改日期：   2021.5.26
版本：           v1.1
--------------------------------------------------------------------
模块描述：       该模块定义裁判系统通讯接收的相关结构体。
--------------------------------------------------------------------
修改记录：
作者         		时间            版本		说明
Zhou Zhicheng		2021.5.26		1.1			基于20210430版官方通讯协议进行移植
												飞镖发射标志位被移除
********************************************************************/

#ifndef RM_RS_V2021_TYPES_H
#define RM_RS_V2021_TYPES_H

#include "stdint.h"


#define	Red_1_Hero		1
#define	Red_2_Engineer	2
#define Red_3_Standard 	3
#define Red_4_Standard  4
#define Red_5_Standard  5
#define Red_6_Aerial    6
#define Red_7_Sentry    7
#define	Red_9_Radar     9
    
#define	Blue_1_Hero     101
#define Blue_2_Engineer 102
#define Blue_3_Standard 103
#define Blue_4_Standard 104
#define Blue_5_Standard 105
#define Blue_6_Aerial   106
#define Blue_7_Sentry   107
#define	Blue_9_Radar    109


#define GameStatusID    			0x0001
#define GameResultID    			0x0002
#define GameRobotHPID   			0x0003
#define EventDataID     			0x0101
#define SupplyProjectileActionID    0x0102
#define RefereeWaringID     		0x0104
#define DartRemainingTimeID     	0x0105
#define GameRobotStatusID       	0x0201
#define PowerHeatDataID     		0x0202
#define GameRobotPosID      		0x0203
#define BuffID      				0x0204
#define AerialRobotEnergyID     	0x0205
#define RobotHurtID     			0x0206
#define ShootDataID     			0x0207
#define BulletRemainingID   		0x0208
#define RFIDStatusID        		0x0209
#define GroundRobotPositionID         0x020B
#define SentryInfoID         0x020D
#define RobotInteractiveDataID  	0x0301
#define RobotCommandID  	0x0303
#define MapRobotDataID  	0x0305
#define MapSentryDataID   0x0307
#define CustomInfoID   0x0308

#define Custom_Data_Length_MAX			113

#ifdef __cplusplus
#pragma pack(1)
#endif 

/* 裁判系统数据接收体 */
/** 比赛状态数据：0x0001    发送频率：1Hz
  * @param	game_type	比赛类型：	1-RoboMaster机甲大师赛
  *									2-RoboMaster机甲大师单项赛
  *									3-ICRA RoboMaster人工智能挑战赛
  *									4-RoboMaster联盟赛3V3
  *									5-RoboMaster联盟赛1V1
  *			game_progress	当前比赛阶段：	0-未开始比赛
  *											1-准备阶段
  *											2-自检阶段
  *											3-5s倒计时
  *											4-对战中
  *											5-比赛结算中
  *			stage_remain_time	当前阶段剩余时间，单位s
  *			SyncTimeStamp		机器人接收到该指令的精确Unix时间，当机载端收到有效的NTP服务器授时后生效
  */
typedef  struct {
	uint8_t game_type: 4;
	uint8_t game_progress: 4;
	uint16_t stage_remain_time;
	uint64_t SyncTimeStamp;
} ext_game_status_t;



/** 比赛结果数据：0x0002    发送频率：比赛结束后发送
  *	@param	winner	0-平局	1-红方胜利	2-蓝方胜利
  */
typedef  struct {
	uint8_t winner;
} ext_game_result_t;



/** 机器人血量数据：0x0003   发送频率：1Hz
* @brief	提供各队机器人血量数据，未上场以及罚下血量为0
  */
typedef  struct {
	uint16_t red_1_robot_HP;
	uint16_t red_2_robot_HP;
	uint16_t red_3_robot_HP;
	uint16_t red_4_robot_HP;
	uint16_t red_5_robot_HP;
	uint16_t red_7_robot_HP;
	uint16_t red_outpost_HP;
	uint16_t red_base_HP;
	uint16_t blue_1_robot_HP;
	uint16_t blue_2_robot_HP;
	uint16_t blue_3_robot_HP;
	uint16_t blue_4_robot_HP;
	uint16_t blue_5_robot_HP;
	uint16_t blue_7_robot_HP;
	uint16_t blue_outpost_HP;
	uint16_t blue_base_HP;
} ext_game_robot_HP_t;



/** 场地事件数据：0x0101    发送频率：事件改变后发送
  *	@param	bit 0-2：	己方补血点状态
  * 			bit 0：	己方补给站1号补血点占领状态，1为已占领
  *				bit 1：	己方补给站2号补血点占领状态，1为已占领
  *				bit 2：	己方补给站3号补血点占领状态，1为已占领
  *			bit 3-5：	己方能量机关状态
  *				bit 3：	打击点占领状态，1为占领
  *				bit 4：	小能量机关激活状态，1为已激活
  *				bit 5：	大能量机关激活状态，1为已激活
  *			bit 6：		己方R2环形高地占领状态，1为已占领
  *			bit 7：		己方R3梯形高地占领状态，1为已占领
  *			bit 8：		己方R4梯形高地占领状态，1为已占领
  *			bit 9：		己方基地护盾状态
  *				1为基地有虚拟护盾血量
  *				0为基地无虚拟护盾血量
  *			bit 10：	己方前哨站状态
  *				1为前哨站存活
  *				0为前哨站被击毁
  */
typedef  struct {
	uint32_t event_type;
} ext_event_data_t;



/** 补给站动作标识：0x0102   发送频率：动作改变后发送    发生范围：己方机器人
  * @param	supply_projectile_id	补给站口ID:	1为1号补给口 2为2号补给口
  *			supply_robot_id			补弹机器人ID: 0为当前无机器人补弹
  *			supply_projectile_step	出弹口开闭状态：0为关闭，1为子弹准备中，2为子弹下落
  *			supply_projectile_num	补弹数量：50/100/150/200
  */
typedef  struct {
	uint8_t supply_projectile_id;
	uint8_t supply_robot_id;
	uint8_t supply_projectile_step;
	uint8_t supply_projectile_num;
} ext_supply_projectile_action_t;



/** 裁判警告信息：0x0104    发送频率：警告发生后发送
  *	@param	level	警告等级：1为黄牌，2为红牌，3为判负
  *			foul_robot_id	犯规机器人ID
  *							判负时，机器人ID为0
  *							黄牌、红牌时，机器人ID为犯规机器人ID
  */
typedef  struct {
	uint8_t level;
	uint8_t foul_robot_id;
  uint8_t count;
} ext_referee_warning_t;



/** 飞镖发射口倒计时：0x0105  发射频率：1Hz    发送范围：己方机器人 
  *	@param	dart_remaining_time		15s倒计时
  */
typedef  struct {
	uint8_t dart_remaining_time;
  uint16_t dart_info;
} ext_dart_remaining_time_t;



/** 比赛机器人状态：0x0201   发送频率：10Hz 
  *	@param	robot_id	本机器人ID
  *			robot_level	机器人等级
  *			remain_HP	机器人剩余血量
  *			max_HP		机器人上限血量
  *			shooter_id1_17mm_cooling_rate	机器人1号17mm枪口每秒冷却值
  *			shooter_id1_17mm_cooling_limit	机器人1号17mm枪口热量上限
  *			shooter_id1_17mm_speed_limit	机器人1号17mm枪口上限速度 单位m/s
  *			shooter_id2_17mm_cooling_rate	机器人2号17mm枪口每秒冷却值
  *			shooter_id2_17mm_cooling_limit	机器人2号17mm枪口热量上限
  *			shooter_id2_17mm_speed_limit	机器人2号17mm枪口上限速度 单位m/s
  *			shooter_id1_42mm_cooling_rate	机器人42mm枪口每秒冷却值
  *			shooter_id1_42mm_cooling_limit	机器人42mm枪口热量上限
  *			shooter_id1_42mm_speed_limit	机器人42mm枪口上限速度 单位m/s
  *			chassis_power_limit			底盘功率限制上限
  *			主控电源输出情况
  *			mains_power_gimbal_output	gimbal口输出	1为有24V输出，0为无24V输出
  *			mains_power_chassis_output	chassis口输出	1为有24V输出，0为无24V输出
  *			mains_power_shooter_output	shooter口输出	1为有24V输出，0为无24V输出
  */
typedef  struct {
	uint8_t robot_id;
	uint8_t robot_level;
	uint16_t remain_HP;
	uint16_t max_HP;
  uint16_t shooter_barrel_cooling_value;
  uint16_t shooter_barrel_heat_limit;
  uint16_t chassis_power_limit;
  uint8_t power_management_gimbal_output : 1;
  uint8_t power_management_chassis_output : 1;
  uint8_t power_management_shooter_output : 1;
} ext_game_robot_status_t;



/** 实时功率热量数据：0x0202  发送频率：50Hz 
  * @param	chassis_volt	底盘输出电压 单位mV
  *			chassis_current	底盘输出电流 单位mA
  *			chassis_power	底盘输出功率 单位W
  *			chassis_power_buffer			底盘功率缓冲 单位J	备注：飞坡根据规则增加至250J
  *			shooter_id1_17mm_cooling_heat	1号17mm枪口热量
  *			shooter_id2_17mm_cooling_heat	2号17mm枪口热量
  *			shooter_id1_42mm_cooling_heat	42mm枪口热量
  */
typedef  struct {
	uint16_t chassis_volt;
	uint16_t chassis_current;
	float chassis_power;
	uint16_t chassis_power_buffer;
	uint16_t shooter_id1_17mm_cooling_heat;
	uint16_t shooter_id2_17mm_cooling_heat;
	uint16_t shooter_id1_42mm_cooling_heat;
} ext_power_heat_data_t;



/** 机器人位置：0x0203     发送频率：10Hz
  *	@param	x	位置x坐标，单位m
  *			y	位置y坐标，单位m
  *			z	位置z坐标，单位m
  *			yaw	位置枪口，单位°
  */
typedef  struct {
	float x;
	float y;
	float yaw;
} ext_game_robot_pos_t;



/** 机器人增益：0x0204     发送频率：1Hz
  *	@param	bit 0:	机器人血量补血状态
  *			bit 1:	枪口热量冷却加速
  *			bit 2:	机器人防御加成
  *			bit 3:	机器人攻击加成
  */
typedef  struct {
	uint8_t recovery_buff;
  uint8_t cooling_buff;
  uint8_t defence_buff;
  uint8_t vulnerability_buff;
  uint16_t attack_buff;
} ext_buff_t;



/** 空中机器人能量状态：0x0205     发送频率：10Hz
  *	@param	attack_time	可攻击时间 单位s	30s递减至0
  */
typedef  struct {
	uint8_t airforce_status;
  uint8_t time_remain;
} aerial_robot_energy_t;

/** 伤害状态：0x0206          发送频率：伤害发生后发送
  *	@param	armor_id	当血量变化类型为装甲伤害，代表装甲ID，其中数值为0~4号代表机器人的五个装甲片，
  *						其他血量变化类型，该变量数值为0
  *			hurt_type	血量变化类型
  *							0x00 装甲伤害扣血
  *							0x01 模块掉线扣血
  *							0x02 超射速扣血
  *							0x03 超枪口热量扣血
  *							0x04 超底盘功率扣血
  *							0x05 装甲撞击扣血
  */
typedef   struct {
	uint8_t armor_id: 4;
	uint8_t hurt_type: 4;
} ext_robot_hurt_t;



/** 实时射击信息：0x0207    发送频率：射击后发送
  *	@param	bullet_type 子弹类型	1为17mm弹丸	2为42mm弹丸
  *			shooter_id	发射机构ID	1为1号17mm发射机构
  *									2为2号17mm发射机构
  *									3为42mm发射机构
  *			bullet_freq		子弹射频 单位Hz
  *			bullet_speed 	子弹射速 单位m/s
  */
typedef   struct {
	uint8_t bullet_type;
	uint8_t shooter_id;
	uint8_t bullet_freq;
	float bullet_speed;
} ext_shoot_data_t;



/** 子弹剩余发射数：0x0208   发送频率：10Hz周期发送   发送范围：所有机器人发送
*	@param	bullet_remaining_num_17mm	17mm子弹剩余发射数目
*			bullet_remaining_num_42mm	42mm子弹剩余发射数目
*			coin_remaining_num			剩余金币数量
  */
typedef  struct {
	uint16_t bullet_remaining_num_17mm;
	uint16_t bullet_remaining_num_42mm;
	uint16_t coin_remaining_num;
} ext_bullet_remaining_t;



/** 机器人RFID状态：0x0209     发送频率：1Hz    发送范围：单一机器人
  *	@param	bit 0:	基地增益点RFID状态
  *			bit 1:	高地增益点RFID状态
  *			bit 2:	能量机关激活点RFID状态
  *			bit 3:	飞坡增益点RFID状态
  *			bit 4:	前哨站增益点RFID状态
  *			bit 5:	资源岛增益点RFID状态
  *			bit 6:	补血点增益点RFID状态
  *			bit 7:	工程机器人补血卡RFID状态
* @brief	RFID状态不完全代表对应的增益或处罚状态，例如敌方已占领的高地增益点，不能获取对应的增益效应
  */
typedef  struct {
	uint32_t rfid_status;
} ext_rfid_status_t;


/*己方地面机器人位置：0x020B*/
typedef struct
{
  float hero_x;
  float hero_y;
  float engineer_x;
  float engineer_y;
  float standard_3_x;
  float standard_3_y;
  float standard_4_x;
  float standard_4_y;
  float standard_5_x;
  float standard_5_y;
}ground_robot_position_t;


/*哨兵相关决策信息，补弹相关：0x020D*/
typedef struct
{
  uint32_t sentry_info;
} sentry_info_t;


/** 交互数据接收信息：0x0301 
*	@param	data_cmd_id	数据段的内容ID
*						0x0200~0x02FF		6+n			己方机器人间通信
*						0x0100				6+2			客户端删除图形
*						0x0101				6+15		客户端绘制一个图形
*						0x0102				6+30		客户端绘制二个图形
*						0x0103				6+75		客户端绘制五个图形
*						0x0104				6+105		客户端绘制七个图形
*						0x0110				6+45		客户端绘制字符图形
*			sender_ID	发送者的ID
*			receiver_ID	接收者的ID
  */
typedef  struct {
	uint16_t data_cmd_id;
	uint16_t sender_ID;
	uint16_t receiver_ID;
} ext_student_interactive_header_data_t;



/** 交互数据 机器人间通信：0x0301 */
typedef  struct {
	uint8_t data[Custom_Data_Length_MAX];
} robot_interactive_data_t;


/** 哨兵自主决策指令：0x0301 子内容ID：0x0120 */
typedef  struct
{
  uint32_t sentry_cmd;
} sentry_cmd_t;


/** 云台手小地图指令：0x0303 
  *	@param	
  *     target_position_x	目标 x 位置坐标，单位 m, 当发送目标机器人 ID 时，该项为 0
  *			target_position_y	目标 y 位置坐标，单位 m, 当发送目标机器人 ID 时，该项为 0
  *			target_position_z	目标 z 位置坐标，单位 m, 当发送目标机器人 ID 时，该项为 0
  *     commd_keyboard 发送指令时，云台手按下的键盘信息 无按键按下则为 0
  *     target_robot_ID 要作用的目标机器人 ID 当发送位置信息时，该项为 0
  */
typedef struct {
  float target_position_x;
  float target_position_y;
  uint8_t commd_keyboard;
  uint8_t target_robot_ID;
  uint8_t cmd_source;
} ext_robot_command_t;


/*雷达标记敌方机器人坐标数据：0x0305*/
typedef  struct
{
  uint16_t target_robot_id;
  float target_position_x;
  float target_position_y;
}map_robot_data_t;



/** 哨兵向空中机器人发坐标数据 ：0x0307 
  *	@param	
  *     intention	:1.到目标点攻击 2.到目标点防守 3.移动到目标点
  *			start_position_x	路径起点X轴坐标，单位 dm, 
  *			start_position_y	路径起点Y轴坐标，单位 dm, 小地图左下角为坐标原点，水平方向右为X轴正方向/
                          竖直向上为Y轴正方向，显示位置将按照场地尺寸与小地图尺寸等比缩放，超出边界位置在边界显示
  *     delta_x[49] 增量相较于上一个点位进行计算
  *     delta_y[49] 增量相较于上一个点位进行计算
  */
#pragma pack(1)
typedef struct
{
  uint8_t intention;
  uint16_t start_position_x;
  uint16_t start_position_y;
  int8_t delta_x[49];
  int8_t delta_y[49];
  uint16_t sender_id;
} map_sentry_data_t;
#pragma pack()


/*己方机器人对选手端发送自定义消息：0x0308*/
typedef  struct
{
  uint16_t sender_id;
  uint16_t receiver_id;
  uint8_t user_data[30];
} custom_info_t;


#pragma pack(1)
typedef struct
{
  uint16_t data_cmd_id;
  uint16_t sender_id;
  uint16_t receiver_id;
  uint8_t confirm_resurrect_flag : 1;
  uint8_t exchange_resurrect_flag : 1;
  uint16_t exchange_bullet_capacity : 11;
  uint8_t remote_exchange_bullet_capacity_cnt : 4;
  uint8_t remote_exchange_HP_cnt : 4;
  uint16_t reserved : 11;
} sentry_decision_data_t;


//己方机器人位置
typedef struct {
    float x_hero;
    float y_hero;
    float x_engineer;
    float y_engineer;
    float x_infantry_3;
    float y_infantry_3;
    float x_infantry_4;
    float y_infantry_4;
    float x_infantry_5;
    float y_infantry_5;
    float x_sentry;
    float y_sentry;
} sentry_self_robot_data_t;


//敌方机器人数据
typedef struct {
    float label_enemy_1;
    float x_enemy_1;
    float y_enemy_1;
    float label_enemy_2;
    float x_enemy_2;
    float y_enemy_2;
    float label_enemy_3;
    float x_enemy_3;
    float y_enemy_3;
    float label_enemy_4;
    float x_enemy_4;
    float y_enemy_4;
} sentry_enemy_robot_data_t;



#pragma pack(1)
typedef struct
{
  uint16_t data_cmd_id;
  uint16_t sender_id;
  uint16_t receiver_id;
  sentry_self_robot_data_t data;
} radar_communication_self_data_t;



#pragma pack(1)
typedef struct
{
  uint16_t data_cmd_id;
  uint16_t sender_id;
  uint16_t receiver_id;
  sentry_enemy_robot_data_t data;
} radar_communication_enemy_data_t;



#ifdef __cplusplus
#pragma pack()
#endif

#endif